package com.heng.a2_tomcat源码分析;

import org.apache.tomcat.util.collections.SynchronizedStack;

import java.io.IOException;
import java.nio.channels.Channel;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.Paths;

public class A1_NioEndPoint {
    /* 1. private volatile ServerSocketChannel serverSock = null; */

    /* 2. private volatile CountDownLatch stopLatch = null; */

    /* 4. private SynchronizedStack<NioChannel> nioChannels; */

    /* 5.  private boolean useInheritedChannel = false; */

    // Channel ic = System.inheritedChannel();

    // this.serverSock = (ServerSocketChannel)ic;
    // 尝试继承已存在的套接字，旧版本与新版本无停机替换，减少系统调用。
    // 在 Tomcat 的 NioEndpoint 中，System.inheritedChannel() 的调用与预绑定套接字（Pre-bound Socket）机制有关。
    // 这个特性允许 Tomcat 重用由父进程（如 systemd 或容器）预先创建和绑定的套接字，而不是在自身启动时重新绑定端口。
    // 预绑定模式（继承已有套接字）
    // 直接使用继承的套接字，无需再次 bind()
    // 当 Tomcat 继承已有套接字后，父进程不再拥有该套接字的控制权，因此不需要（也不应该）由父进程关闭它。相反，Tomcat 会在自身关闭时负责关闭这个继承的套接字
    // 父进程创建套接字后，由 Tomcat 负责关闭它，避免资源泄漏。
    //


    // SocketAddress sa = JreCompat.getInstance().getUnixDomainSocketAddress(this.getUnixDomainSocketPath());
    // JreCompat.getInstance()：这是 Tomcat 里的一个兼容层，其作用是处理不同 Java 运行时环境（JRE）之间的差异。
    // getUnixDomainSocketAddress(...)：该方法会依据指定的路径创建一个 Unix 域套接字地址。
    // 虽然 JVM 提供了 “一次编写，到处运行” 的跨平台能力，但不同版本的 JRE（如 Java 8 vs Java 17）可能存在 API 差异，导致兼容性问题。
    // JRE ≠ JDK：JRE 是运行环境，JDK 是开发工具包。
    // JDK = JRE + 开发工具

    //JDK（Java Development Kit）
    //是开发 Java 程序的工具包，包含：
    //JRE
    //编译器（javac）
    //调试工具（jdb、jconsole）
    //文档工具（javadoc）
    //其他开发工具


    /* 这里面有很多都是 XXX extends XXXBase */

    // Acceptor
    // 负责连接事件

    /* setSocketOptions(SocketChannel socket)  */
    // 这个方法是干嘛的？

    // protected Map<U, SocketWrapperBase<S>> connections = new ConcurrentHashMap();
    //             NioSocketWrapper newWrapper = new NioSocketWrapper((NioChannel)channel, this);
    //            ((NioChannel)channel).reset(socket, newWrapper);
    //            this.connections.put(socket, newWrapper);
    // 包装socketChannel

    /* Socket和SocketChannel之间的区别 */
    // 二者都是套接字，Socket是BIO套接字，SocketChannel是NIO套接字

    /* serverSocketAccept()  */
    // 这个方法是接收客户端的连接请求


    /* private final SynchronizedQueue<PollerEvent> events = new SynchronizedQueue(); */
    // 同步队列

    // addEvent(PollerEvent event)
    // this.events.offer(event);
    // this.wakeupCounter.incrementAndGet() == 0L  // 当计数器溢出回零时（即达到Long.MAX_VALUE后变为Long.MIN_VALUE），调用wakeup()
    // this.selector.wakeup();


    /* NioSocketWrapper */
    // NioChannel封装了SocketChannel
    // NioSocketWrapper包装了NioChannel
    // NioSocketWrapper.getNioChannel().write() -> ... -> 最终调用的是SocketChannel.write()

    /* read(boolean block, ByteBuffer to) */

    /* protected volatile SocketBufferHandler socketBufferHandler = null; */

    /* doWrite(boolean block, ByteBuffer buffer)  */



    /* SocketWrapperBase类：
     private final AtomicReference<Object> currentProcessor;
      原子引用类
      */

    // SocketWrapper：封装底层SocketChannel，管理连接状态
    // NioSocketWrapper  封装单个 TCP 连接的状态和操作

    public static void main(String[] args) throws IOException {
        SynchronizedStack<Integer> stack = new SynchronizedStack<>();

        stack.push(1);
        stack.push(2);

        System.out.println(stack);

        FileChannel fileChannel = FileChannel.open(Paths.get("/"));
        Channel channel = ServerSocketChannel.open();

//        fileChannel.transferTo(0L, 0L, (WritableByteChannel) channel);
    }

}
